package com.whfc.fse.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.enums.BindFlag;
import com.whfc.common.enums.NetState;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.DateUtil;
import com.whfc.common.util.PageUtil;
import com.whfc.fse.dao.FseBridgeDataMapper;
import com.whfc.fse.dao.FseBridgeMapper;
import com.whfc.fse.dto.FseBridgeDTO;
import com.whfc.fse.dto.FseBridgeDataDTO;
import com.whfc.fse.dto.FseBridgeDataLogDTO;
import com.whfc.fse.dto.FseOperatorDTO;
import com.whfc.fse.entity.FseBridge;
import com.whfc.fse.entity.FseBridgeData;
import com.whfc.fse.param.FseBridgeAddParam;
import com.whfc.fse.param.FseBridgeBindParam;
import com.whfc.fse.param.FseBridgeEditParam;
import com.whfc.fse.param.FseBridgeUnbindParam;
import com.whfc.fse.service.FseBridgeService;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.influx.dao.FseBridgeDataLogDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @Description 架桥机
 * @Author hw
 * @Date 2021-06-01 16:51
 * @Version 1.0
 */
@DubboService(interfaceClass = FseBridgeService.class, version = "1.0.0")
public class FseBridgeServiceImpl implements FseBridgeService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FseBridgeMapper fseBridgeMapper;

    @Autowired
    private FseBridgeDataMapper fseBridgeDataMapper;

    @Autowired
    private FseBridgeDataLogDao fseBridgeDataLogDao;

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;

    @Override
    public void add(FseBridgeAddParam param) throws BizException {
        logger.info("新增架桥机设备,param：{}", param);
        FseBridge fseBridge = new FseBridge();
        BeanUtils.copyProperties(param, fseBridge);
        //保存操作手
        List<FseOperatorDTO> list = param.getOperatorList();
        if (list != null && !list.isEmpty()) {
            fseBridge.setOperators(JSON.toJSONString(list));
        }
        fseBridgeMapper.insertSelective(fseBridge);
        //初始化架桥机初始数据
        FseBridgeData bridgeData = new FseBridgeData();
        bridgeData.setBridgeId(fseBridge.getId());
        fseBridgeDataMapper.insertSelective(bridgeData);
    }

    @Override
    public void edit(FseBridgeEditParam param) throws BizException {
        logger.info("修改架桥机设备,param：{}", param);
        Integer bridgeId = param.getBridgeId();
        FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(bridgeId);
        if (fseBridge == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "架桥机不存在");
        }
        BeanUtils.copyProperties(param, fseBridge);
        //保存操作手
        List<FseOperatorDTO> list = param.getOperatorList();
        fseBridge.setOperators(JSON.toJSONString(list));
        fseBridgeMapper.updateByPrimaryKeySelective(fseBridge);
    }

    @Override
    public void del(Integer bridgeId) throws BizException {
        logger.info("删除架桥机,bridgeId:{}", bridgeId);
        FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(bridgeId);
        if (fseBridge == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该架桥机不存在");
        }
        if (StringUtils.isNotBlank(fseBridge.getSn())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该架桥机已绑定硬件,不能删除");
        }
        fseBridgeMapper.del(bridgeId);
        fseBridgeDataMapper.logicDelByBridgeId(bridgeId);
    }

    @Override
    public PageData<FseBridgeDTO> list(Integer deptId, String keyword, Integer bindFlag, Integer netState, Integer pageNum, Integer pageSize) throws BizException {
        logger.info("架桥机列表(分页),pageNum:{},pageSize:{},deptId:{},keyword:{},bindFlag:{},netState:{}",
                pageNum, pageSize, deptId, keyword, bindFlag, netState);
        PageHelper.startPage(pageNum, pageSize);
        List<FseBridgeDTO> list = fseBridgeMapper.selectFseBridgeByDeptId(Collections.singletonList(deptId), keyword, bindFlag, netState);
        PageHelper.clearPage();

        for (FseBridgeDTO fseBridgeDTO : list) {
            handlerOperators(fseBridgeDTO);
        }
        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    public List<FseBridgeDTO> list(Integer deptId, String keyword, Integer bindFlag, Integer netState) throws BizException {
        logger.info("架桥机列表(不分页),deptId:{},keyword:{},bindFlag:{},netState:{}", deptId, keyword, bindFlag, netState);
        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<FseBridgeDTO> list = fseBridgeMapper.selectFseBridgeByDeptId(deptIds, keyword, bindFlag, netState);

        for (FseBridgeDTO fseBridgeDTO : list) {
            handlerOperators(fseBridgeDTO);
        }
        return list;
    }


    @Override
    public FseBridgeDTO details(Integer bridgeId) throws BizException {
        logger.info("架桥机详情,bridgeId:{}", bridgeId);
        FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(bridgeId);
        FseBridgeDTO fseBridgeDTO = new FseBridgeDTO();
        if (fseBridge != null) {
            BeanUtils.copyProperties(fseBridge, fseBridgeDTO);
            handlerOperators(fseBridgeDTO);
        }
        return fseBridgeDTO;
    }

    @Override
    public void bind(FseBridgeBindParam param) throws BizException {
        logger.info("架桥机绑定硬件服务,param:{}", param);
        Integer bridgeId = param.getBridgeId();
        FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(bridgeId);
        if (fseBridge == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该架桥机不存在");
        }
        String sn = param.getSn();
        String platform = param.getPlatform();
        FseBridge bridge = fseBridgeMapper.selectByPlatformAndSn(platform, sn);
        if (bridge != null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该硬件已被绑定");
        }
        fseBridgeMapper.updateBindFlag(bridgeId, platform, BindFlag.BIND.getValue(), sn, NetState.OFFLINE.getValue());
    }

    @Override
    public void unbind(FseBridgeUnbindParam param) throws BizException {
        logger.info("架桥机解绑硬件服务,param:{}", param);
        Integer bridgeId = param.getBridgeId();
        FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(bridgeId);
        if (fseBridge == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该架桥机不存在");
        }
        fseBridgeMapper.updateBindFlag(bridgeId, null, BindFlag.UNBIND.getValue(), null, NetState.OFFLINE.getValue());
    }

    @Override
    public FseBridgeDataDTO monitor(Integer bridgeId) throws BizException {
        logger.info("架桥机监测,gantryId:{}", bridgeId);
        FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(bridgeId);
        if (fseBridge == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "龙门吊不存在");
        }
        FseBridgeData fseBridgeData = fseBridgeDataMapper.selectByBridgeId(bridgeId);
        FseBridgeDataDTO dataDTO = new FseBridgeDataDTO();
        if (fseBridgeData == null) {
            return dataDTO;
        }
        BeanUtils.copyProperties(fseBridgeData, dataDTO);
        Date now = new Date();
        Date startTime = DateUtil.getDateBegin(now);
        Date endTime = DateUtil.getDateEnd(now);
        int frontLiftWarnNum = 0;
        int backLiftWarnNum = 0;
        int windWarnNum = 0;
        List<FseBridgeDataLogDTO> logs = fseBridgeDataLogDao.selectBridgeDataLogListByBridgeId(bridgeId, startTime, endTime);
        if (logs != null && !logs.isEmpty()) {
            frontLiftWarnNum = logs.stream().mapToInt(FseBridgeDataLogDTO::getFrontLiftTimeWarnNum).sum();
            backLiftWarnNum = logs.stream().mapToInt(FseBridgeDataLogDTO::getBackLiftTimeWarnNum).sum();
            windWarnNum = logs.stream().mapToInt(FseBridgeDataLogDTO::getWindTimeWarnNum).sum();
        }
        dataDTO.setFrontLiftWarnNum(frontLiftWarnNum);
        dataDTO.setBackLiftWarnNum(backLiftWarnNum);
        dataDTO.setWindWarnNum(windWarnNum);
        return dataDTO;
    }

    @Override
    public List<FseBridgeDataLogDTO> bridgeLog(Integer bridgeId, Date time) {
        logger.info("桥架机历史记录,bridgeId:{},time:{}", bridgeId, time);
        Date startTime = DateUtil.getDateBegin(time);
        Date endTime = DateUtil.getDateEnd(time);
        return fseBridgeDataLogDao.selectBridgeDataLogListByBridgeId(bridgeId, startTime, endTime);
    }


    /**
     * 处理操作手
     *
     * @param fseBridgeDTO
     */
    private void handlerOperators(FseBridgeDTO fseBridgeDTO) {
        String operators = fseBridgeDTO.getOperators();
        List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
        if (operatorList == null) {
            operatorList = new ArrayList<>();
        }
        fseBridgeDTO.setOperatorList(operatorList);
        fseBridgeDTO.setOperators(null);
    }
}
